#include <zemb/BaseType.h>
#include <zemb/Tracer.h>
#include <zemb/ArgUtil.h>
#include <zemb/Thread.h>
#include <zemb/ProcUtil.h>
#include <zembx/Config.h>
using namespace zemb;

#ifdef OS_CYGWIN
void TestConfig(void)
{
    TRACE_ERR("Not support Config.\n");
}
#else
#include <stdlib.h>
#include <iostream>
using namespace std;
using namespace zemb;
using namespace zembx;
/** Config Brief Introduce
 *  配置文件的数据类型及格式
 *  int = 10001;         //整形值
 *  float = 1.23;       
 *  double = 3.1415926;     //浮点值
 *  string = "Jim";       //字符串
 *  array = [1,-1,1,0]; //数组,用[]表示
 *  group = ({item=1;},{item=2});//配置组,用()包含
 *  setting:    //配置,用{}包含
 *  {
 *      key1="strValue";
 *      subsetting:
 *      {
 *          array1=({...},{...});
 *      }
 *  } 
 *  整个文件是一个rootSetting,下面包含一个或多个setting
 *  每个setting里可以包含若干子setting和其他数据类型
 */

#define CONFIG_FILE_NAME        "config-test.cfg"
#define CONFIG_SAVE_FILE_NAME   "config-test-save.cfg"
#define CONFIG_NEW_FILE_NAME    "config-test-new.cfg"

#if 0      /* 测试文件用例: config-test.cfg */
int = 1;
float = 2.0;
double = 3.1415926;
string = "Jim";
array = [ 1, -1, 1, 0 ];
double_array = [1.0,2.1,3.2,4.3];
string_array = ["one","two","three","four"];
list = ( 
    {
        item = 8;
    }, 
    {
        item = 9;
    } );
group : 
{
    string = "fergus中文";
    subgroup : 
    {
        array = [ 1, 2, 3, 4 ];
    };
}; 
#endif

void testConfig(void)
{
    while(1)
    {
        TRACE_DBG("Config Test --- q:quit.t:test\n");
		InputReader reader;
		reader.waitInput();
        if (reader.isString("q") || reader.isString("quit")) 
        {
            return;
        }
        else
        {            
            Config config;

            /* 读测试 */
            TRACE_YELLOW("---------Config init Test--------------\n");
            if(!config.initWithFile(CONFIG_FILE_NAME))
            {
                TRACE_ERR("Open config file failed:%s.\n",CONFIG_FILE_NAME);
                continue;
            }

            /* 读测试 */
            TRACE_YELLOW("---------Config Read Test--------------\n");
            cout<<"int:"<<config["int"].toInt()<<endl;
            cout<<"float:"<<config["float"].toDouble()<<endl;
            cout<<"double:"<<config["double"].toDouble()<<endl;
            cout<<"string:"<<config["string"].toString()<<endl;
            cout<<"array:"<<config["array"].toIntArray().serialize()<<endl;
            cout<<"double_array:"<<config["double_array"].toDoubleArray().serialize()<<endl;
            cout<<"double_array size="<<config["double_array"].size()<<endl;
            cout<<"string_array:"<<config["string_array"].toStringArray().serialize()<<endl;
            cout<<"string_array size="<<config["string_array"].size()<<endl;
            cout<<"list[0][item]:"<<config["list"][0]["item"].toInt()<<endl;
            cout<<"list[1][item]:"<<config["list"][1]["item"].toInt()<<endl;
            cout<<"group[string]:"<<config["group"]["string"].toString()<<endl;
            cout<<"group[subgroup][array]:"<<config["group"]["subgroup"]["array"].toIntArray().serialize()<<endl;
            
            TRACE_YELLOW("---------Settings Read Test--------------\n");
            Settings listSettings = config["list"];
            cout<<"listSettings size="<<listSettings.size()<<endl;
            cout<<"listSettings[0][item]:"<<listSettings[0]["item"].toInt()<<endl;
            cout<<"listSettings[1][item]:"<<listSettings[1]["item"].toInt()<<endl;
            
            #if 1
            /* 写测试 */
            TRACE_YELLOW("---------Config Write Test--------------\n");
            config["int"]=100;
            config["float"]=200.123;
            config["double"]=300.456;
            config["string"]="Lucy";

            /* 数组修改 */
            IntArray array;
            array.initWithString("[100,200,300,400]");
            config["array"]=array;

            /* List修改 */
            config["list"][0]["item"]=400;
            config["list"][1]["item"]=500;

            /* Group修改 */
            config["group"]["string"]="ByeBye";

            array.initWithString("[500,600,700,800,900]");
            config["group"]["subgroup"]["array"]=array;
            #endif

            #if 1   /* 增加配置项 */
            TRACE_YELLOW("---------Config Add Test--------------\n");
            config.rootSettings().addInt("int_new",1000);
            config.rootSettings().addDouble("double_new",2000.123);
            config.rootSettings().addString("string_new","new settings");
            array.initWithString("[1500,1600,1700,1800,1900]");
            config.rootSettings().addArray("array_new",array);
 
            config.rootSettings().addList("list_new");
            config["list_new"].addGroup();
            config["list_new"][0].addInt("item_new",4000);
            config["list_new"][0].addArray("array_new",array);
            config["list_new"][0].addList("list_new_0");
            config["list_new"][0]["list_new_0"].addGroup();
            config["list_new"][0]["list_new_0"][0].addInt("item_new",4000);
            config["list_new"][0]["list_new_0"][0].addArray("array_new",array);
            
            config["list_new"].addGroup();
            config["list_new"][1].addInt("item_new",5000);
            config["list_new"][1].addArray("array_new",array);
            config["list_new"][1].addGroup("group_new_1");
            config["list_new"][1]["group_new_1"].addInt("item_new",4000);
            config["list_new"][1]["group_new_1"].addArray("array_new",array);
            config["list_new"][1]["group_new_1"].addList("list_new_1");

            config.rootSettings().addGroup("group_new");
            config["group_new"].addString("string_new","new World.");
            config["group_new"].addArray("array_new",array);
            config["group_new"].addList("list_new");
            config["group_new"]["list_new"].addGroup();
            config["group_new"]["list_new"][0].addInt("item_new",4000);
            config["group_new"]["list_new"][0].addArray("array_new",array);
            
            #endif

            /* 保存测试 */
            TRACE_YELLOW("---------Config Save Test--------------\n");
            if(!config.saveAsFile(CONFIG_SAVE_FILE_NAME))
            {
                TRACE_ERR("Save config file failed:%s.\n",CONFIG_SAVE_FILE_NAME);
                continue;
            }
            
            TRACE_YELLOW("---------show File: %s --------------\n",CONFIG_SAVE_FILE_NAME);
            string cmd = "cat ";
            cmd += CONFIG_SAVE_FILE_NAME;
			TRACE_DBG("%s:\n",CSTR(ProcUtil::runCommand(cmd)));

            TRACE_YELLOW("---------Config New Test--------------\n");
            Config config_new;
            config_new.rootSettings().addInt("int", 1);
            config_new.rootSettings().addGroup("group");
            config_new.saveAsFile(CONFIG_NEW_FILE_NAME);
        }
    }
}
#endif